/*
作者： 黄江南
目的：
1、学习《Linux网络编程》中第三章p31的fcntl函数
*/

//文件execve.c，使用execve（）函数调用processimage
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>

void printpos(char* string, int fildes)
{
	long pos;
	if((pos = lseek(fildes, 0L, 1)) < 0L);
	printf("%s: %ld\n", string, pos);
}

int main(int argc,char * argv[],char ** environ)
{
	printf("Exec example!\n");
	pid_t pid;
	int   stat_val;

	char *newargv[] = {NULL, "hello", "world", NULL};
	char *newenviron[] = {NULL};

	// newargv[0] = argv[1];

	printf("next c program that should be executed: %s\n", argv[1]);

	int fd; // 文件描述符
	char buf[10]; // 数据缓冲区

	if( (fd=open("data", 00)) < 0) { // 00 = O_RDONLY 只读文件
		perror("open failed");
		exit(1);
	}
	read(fd, buf, 10);
	printpos("Before fork", fd);

	// fcntl(fd, F_SETFD, 1); // 关闭文件fd

	pid = fork();
	switch(pid) {
		case -1:
			perror("Process Creation failed\n");
			exit(1);
		case 0:
			printf("Child process is running\n");
			// printf("Execve pid = %d ,parentpid = %d\n",getpid(),getppid());
			// printf("Execve uid = %d,gid =%d\n",getuid(),getgid());

			printpos("Child before read", fd);
			read(fd, buf, 10);
			printpos("Child After read", fd);


			newargv[1] = (char)fd;
			execve(argv[1], newargv, newenviron);
 
			//以下代码永远得不到运行的机会
			printf("process never go to here!\n");
			exit(0);
		default:
			wait(NULL);

			printpos("Parent before read", fd);
			read(fd, buf, 10);
			printpos("Parent After read", fd);

			printf("Parent process is running\n");
			break;
	}
 
	wait(&stat_val);
	exit(0);
}
